﻿using System;
using System.Drawing;
using System.Linq.Expressions;
using System.Windows.Forms;

namespace MyCalculator
{
    public partial class ScientificCalculator : UserControl
    {
        private double? firstNumber = null;
        private string currentNumber = "0";
        private char? pendingOperation = null;
        private bool newNumber = true;

        public ScientificCalculator()
        {
            InitializeComponent();
            InitializeEvents();
        }

        private void InitializeEvents()
        {
            // 数字按钮事件
            btn0.Click += NumberClick;
            btn1.Click += NumberClick;
            btn2.Click += NumberClick;
            btn3.Click += NumberClick;
            btn4.Click += NumberClick;
            btn5.Click += NumberClick;
            btn6.Click += NumberClick;
            btn7.Click += NumberClick;
            btn8.Click += NumberClick;
            btn9.Click += NumberClick;

            // 操作按钮
            btnAdd.Click += OperationClick;
            btnSubtract.Click += OperationClick;
            btnMultiply.Click += OperationClick;
            btnDivide.Click += OperationClick;

            // 科学函数按钮事件
            btnSin.Click += SinClick;
            btnCos.Click += CosClick;
            btnTan.Click += TanClick;
            btnLog.Click += LogClick;
            btnLn.Click += LnClick;
            btnExp.Click += ExpClick;
            btnSqrt.Click += SqrtClick;
            btnPow.Click += PowClick;
            btnFactorial.Click += FactorialClick;
            btnPI.Click += PIClick;
            btnE.Click += EClick;

            // 功能按钮
            btnCE.Click += (s, e) => ClearEntry();
            btnC.Click += (s, e) => ClearAll();
            btnBackspace.Click += BackspaceClick;
            btnDecimal.Click += DecimalClick;
            btnSign.Click += SignClick;
            btnEquals.Click += EqualsClick;
        }

        private void UpdateDisplay()
        {
            txtResult.Text = currentNumber;
            if (txtResult.Text.Length > 12)
                txtResult.Font = new Font("Segoe UI", 20F);
            else
                txtResult.Font = new Font("Segoe UI", 24F);
        }

        // 按下数字键
        private void NumberClick(object sender, EventArgs e)
        {
            var button = (Button)sender;
            if (newNumber)
            {
                currentNumber = "0";
                newNumber = false;
            }

            if (currentNumber == "0")
                currentNumber = button.Text;
            else
                currentNumber += button.Text;

            UpdateDisplay();
        }

        // 按下操作键
        private void OperationClick(object sender, EventArgs e)
        {
            var button = (Button)sender;
            if (double.TryParse(currentNumber, out double number))
            {
                if (firstNumber == null)
                {
                    firstNumber = number;
                    pendingOperation = button.Text[0];
                    txtExpression.Text = $"{firstNumber} {pendingOperation} ";
                    newNumber = true;
                }
                else
                {
                    txtExpression.Text = $"{firstNumber} {pendingOperation} {number} ";
                    Calculate();
                    pendingOperation = button.Text[0];
                    txtExpression.Text = $"{currentNumber} {pendingOperation} ";
                }
            }
        }

        // 按下等号键
        private void EqualsClick(object sender, EventArgs e)
        {
            if (firstNumber != null && pendingOperation != null)
            {
                string secondNumber = currentNumber;
                txtExpression.Text = $"{firstNumber} {pendingOperation} {secondNumber} = ";
                Calculate();
                txtExpression.Text += currentNumber;
                firstNumber = null;
                pendingOperation = null;
            }
        }

        // 进行运算操作
        private void Calculate()
        {
            if (double.TryParse(currentNumber, out double secondNumber))
            {
                try
                {
                    if (firstNumber == null)
                    {
                        currentNumber = "0";
                        UpdateDisplay();
                        return;
                    }

                    switch (pendingOperation)
                    {
                        case '+':
                            firstNumber += secondNumber;
                            break;
                        case '-':
                            firstNumber -= secondNumber;
                            break;
                        case '×':
                            firstNumber *= secondNumber;
                            break;
                        case '÷':
                            if (secondNumber == 0)
                                throw new DivideByZeroException();
                            firstNumber /= secondNumber;
                            break;
                    }
                    currentNumber = firstNumber?.ToString("G15").TrimEnd('0').TrimEnd('.') ?? "0";
                    UpdateDisplay();
                    newNumber = true;
                }
                catch (DivideByZeroException)
                {
                    ClearAll();
                    txtResult.Text = "不能除以零";
                }
            }
        }


        // 清除当前输入
        private void ClearEntry()
        {
            currentNumber = "0";
            UpdateDisplay();
        }

        // 清除所有
        private void ClearAll()
        {
            firstNumber = null;
            pendingOperation = null;
            currentNumber = "0";
            txtExpression.Text = "";
            UpdateDisplay();
        }

        // 撤销一位
        private void BackspaceClick(object sender, EventArgs e)
        {
            if (currentNumber.Length > 0)
            {
                currentNumber = currentNumber.Substring(0, currentNumber.Length - 1);
                if (currentNumber == "") currentNumber = "0";
                UpdateDisplay();
            }
        }

        // 添加小数点
        private void DecimalClick(object sender, EventArgs e)
        {
            if (!currentNumber.Contains("."))
            {
                currentNumber += ".";
                UpdateDisplay();
            }
        }

        // 取相反数
        private void SignClick(object sender, EventArgs e)
        {
            if (currentNumber != "0")
            {
                if (currentNumber.StartsWith("-"))
                    currentNumber = currentNumber.Substring(1);
                else
                    currentNumber = "-" + currentNumber;
                UpdateDisplay();
            }
        }

        // 三角函数
        private void SinClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Sin(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"sin({num})";
            }
        }

        private void CosClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Cos(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"cos({num})";
            }
        }

        private void TanClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Tan(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"tan({num})";
            }
        }

        // 对数函数
        private void LogClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Log10(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"log({num})";
            }
        }

        private void LnClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Log(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"ln({num})";
            }
        }

        // 指数函数
        private void ExpClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Exp(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"exp({num})";
            }
        }

        // 平方根
        private void SqrtClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double num))
            {
                currentNumber = Math.Sqrt(num).ToString("G10");
                UpdateDisplay();
                txtExpression.Text = $"√({num})";
            }
        }

        // 幂运算
        private void PowClick(object sender, EventArgs e)
        {
            if (double.TryParse(currentNumber, out double baseNum))
            {
                firstNumber = baseNum;
                pendingOperation = '^';
                txtExpression.Text = $"{baseNum}^";
                newNumber = true;
            }
        }

        // 阶乘
        private void FactorialClick(object sender, EventArgs e)
        {
            if (int.TryParse(currentNumber, out int n) && n >= 0)
            {
                int result = 1;
                for (int i = 2; i <= n; i++)
                    result *= i;
                currentNumber = result.ToString();
                UpdateDisplay();
                txtExpression.Text = $"{n}!";
            }
        }

        // 插入常数
        private void PIClick(object sender, EventArgs e)
        {
            currentNumber = newNumber ? Math.PI.ToString() : currentNumber + Math.PI.ToString();
            UpdateDisplay();
            txtExpression.Text = "π";
        }

        private void EClick(object sender, EventArgs e)
        {
            currentNumber = newNumber ? Math.E.ToString() : currentNumber + Math.E.ToString();
            UpdateDisplay();
            txtExpression.Text = "e";
        }
    }
}
